package com.hsteach.service.calendar;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.google.common.collect.Lists;
import com.hsteach.common.core.domain.model.AuthInfo;
import com.hsteach.common.exception.ServiceException;
import com.hsteach.common.utils.DateUtils;
import com.hsteach.common.utils.SecurityUtils;
import com.hsteach.common.utils.StringUtils;
import com.hsteach.dao.domain.calendar.CalendarDay;
import com.hsteach.dao.domain.calendar.CalendarHoliday;
import com.hsteach.dao.domain.calendar.CalendarPlan;
import com.hsteach.dao.mapper.calendar.CalendarDayMapper;
import com.hsteach.dao.mapper.calendar.CalendarHolidayMapper;
import com.hsteach.dao.mapper.calendar.CalendarPlanMapper;
import com.hsteach.enums.BooleanEnum;
import com.hsteach.enums.HolidayTypeEnum;
import com.hsteach.framework.feign.client.holiday.vo.Holiday;
import com.hsteach.framework.feign.client.holiday.vo.HolidayType;
import com.hsteach.framework.feign.client.upload.vo.UploadRet;
import com.hsteach.framework.feign.client.xgk.dto.ret.GetYearListRet;
import com.hsteach.framework.feign.client.xgk.dto.ret.SemAddVacation;
import com.hsteach.framework.web.service.UploadService;
import com.hsteach.service.cookmenu.CookmenuWeekService;
import com.hsteach.service.third.HolidayService;
import com.hsteach.service.third.XgkService;
import com.hsteach.util.ChineseNumToArabicNumUtil;
import com.hsteach.web.controller.calendar.dto.AddCalendarDto;
import com.hsteach.web.controller.calendar.dto.AddHolidayDto;
import com.hsteach.web.controller.calendar.dto.UpdateDayDto;
import com.hsteach.web.controller.calendar.vo.CalendarDayVo;
import com.hsteach.web.controller.calendar.vo.CalendarMonth;
import com.hsteach.web.controller.calendar.vo.CalendarWeek;
import com.hsteach.web.controller.common.vo.SemMonth;
import com.hsteach.web.controller.cookmenu.vo.SemWeek;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.hsteach.dao.mapper.calendar.CalendarMapper;
import com.hsteach.dao.domain.calendar.Calendar;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

/**
 * 周行事历主Service业务层处理
 *
 * @author fanxquer
 * @date 2023-11-28
 */
@Service
public class CalendarService
{
    @Autowired
    private CalendarMapper calendarMapper;

    @Autowired
    private HolidayService holidayService;

    @Autowired
    private CalendarPlanMapper calendarPlanMapper;

    @Autowired
    private XgkService xgkService;

    @Autowired
    private CookmenuWeekService cookmenuWeekService;

    @Autowired
    private CalendarDayMapper calendarDayMapper;

    @Autowired
    private CalendarHolidayMapper calendarHolidayMapper;

    @Autowired
    private UploadService uploadService;

    /**
     * 查询周行事历主
     *
     * @param id 周行事历主主键
     * @return 周行事历主
     */
    public Calendar selectCalendarById(Long id)
    {
        return calendarMapper.selectCalendarById(id);
    }

    /**
     * 查询周行事历主列表
     *
     * @param calendar 周行事历主
     * @return 周行事历主
     */
    public List<Calendar> selectCalendarList(Calendar calendar)
    {
        return calendarMapper.selectCalendarList(calendar);
    }

    /**
     * 新增周行事历主
     *
     * @param calendar 周行事历主
     * @return 结果
     */
    public int insertCalendar(Calendar calendar)
    {
        calendar.setCreateTime(DateUtils.getNowDate());
        return calendarMapper.insertCalendar(calendar);
    }

    public int add(AddCalendarDto dto)
    {
        LocalDate begin = dto.getCalendarBegin().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        LocalDate end = dto.getCalendarEnd().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        long between = ChronoUnit.DAYS.between(begin, end);
        if (between > 365) {
            throw new ServiceException("时间范围不能超过365天");
        }
        AuthInfo authInfo = SecurityUtils.getAuthInfo();
        Calendar calendar = new Calendar();
        BeanUtils.copyProperties(dto, calendar);
        calendar.setCreateBy(authInfo.getPersonId());
        calendar.setOrgCode(authInfo.getOrgCode());
        calendar.setCreateTime(DateUtils.getNowDate());
        calendar.setDelStatus(BooleanEnum.TRUE.getCode());
        return calendarMapper.insertCalendar(calendar);
    }

    @Transactional(rollbackFor = Exception.class)
    public Boolean  addHoliday(AddHolidayDto dto) {
        if (!dto.getHolidayName().equals("寒假") && !dto.getHolidayName().equals("暑假")) {
            List<Holiday> holidays = holidayService.getHolidays(DateUtils.parseDateToStr(DateUtils.YYYY, dto.getHolidayDay()));
            Map<String, Holiday> holidayMap = holidays.stream().collect(Collectors.toMap(Holiday::getName, e -> e, (v1, v2) -> v2));
            Holiday holiday = holidayMap.get(dto.getHolidayName());
            if (holiday == null) {
                throw new ServiceException("该年没有" + dto.getHolidayName() + "节日");
            }
        }
            calendarHolidayMapper.deleteByCalendarIdAndName(dto.getCalendarId(), dto.getHolidayName());
            CalendarHoliday calendarHoliday = new CalendarHoliday();
            calendarHoliday.setCalendarId(dto.getCalendarId());
            calendarHoliday.setHolidayName(dto.getHolidayName());
            calendarHoliday.setDay(dto.getHolidayDay());
            calendarHoliday.setHolidayBegin(dto.getHolidayBegin());
            calendarHoliday.setHolidayEnd(dto.getHolidayEnd());
            calendarHoliday.setDelStatus(BooleanEnum.TRUE.getCode());
            AuthInfo authInfo = SecurityUtils.getAuthInfo();
            calendarHoliday.setOrgCode(authInfo.getOrgCode());
            calendarHoliday.setCreateBy(authInfo.getPersonId());
            calendarHolidayMapper.insertCalendarHoliday(calendarHoliday);
        return true;
    }
    /**
     * 修改周行事历主
     *
     * @param calendar 周行事历主
     * @return 结果
     */
    public int updateCalendar(Calendar calendar)
    {
        calendar.setUpdateTime(DateUtils.getNowDate());
        return calendarMapper.updateCalendar(calendar);
    }

    public int editDay(UpdateDayDto dto)
    {
        CalendarDay query = new CalendarDay();
        query.setDelStatus(BooleanEnum.TRUE.getCode());
        query.setOrgCode(SecurityUtils.getAuthInfo().getOrgCode());
        query.setCalendarId(dto.getId());
        query.setDay(dto.getDay());
        List<CalendarDay> calendarDays = calendarDayMapper.selectCalendarDayList(query);
        if (calendarDays.isEmpty()) {
            query.setWorkFlg(dto.getWorkFlg());
            query.setCreateBy(SecurityUtils.getAuthInfo().getPersonId());
            return calendarDayMapper.insertCalendarDay(query);
        } else {
            CalendarDay calendarDay = calendarDays.get(0);
            query.setId(calendarDay.getId());
            query.setWorkFlg(dto.getWorkFlg());
            return calendarDayMapper.updateCalendarDay(query);
        }
    }

    /**
     * 批量删除周行事历主
     *
     * @param ids 需要删除的周行事历主主键
     * @return 结果
     */
    public int deleteCalendarByIds(Long[] ids)
    {
        return calendarMapper.deleteCalendarByIds(ids);
    }

    /**
     * 删除周行事历主信息
     *
     * @param id 周行事历主主键
     * @return 结果
     */
    public int deleteCalendarById(Long id)
    {
        return calendarMapper.deleteCalendarById(id);
    }

    public List<Holiday> getHolidays(Long id) {
        Calendar calendar = calendarMapper.selectCalendarById(id);
        if (calendar == null) {
            throw new ServiceException("事历表不存在");
        }
        List<Holiday> holidays = holidayService.getHolidays(calendar.getCalendarBegin(), calendar.getCalendarEnd());
        Date calendarBegin = calendar.getCalendarBegin();
        Date calendarEnd = calendar.getCalendarEnd();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Holiday winter = new Holiday();
        winter.setName("寒假");
        winter.setHoliday(dateFormat.format(calendarBegin));
        winter.setVacation(getFormattedDatesBetween(calendarBegin, calendarEnd));
        holidays.add(winter);
        Holiday summer = new Holiday();
        summer.setName("暑假");
        summer.setHoliday(dateFormat.format(calendarBegin));
        summer.setVacation(getFormattedDatesBetween(calendarBegin, calendarEnd));
        holidays.add(summer);
        return holidays;
    }

    private String getFormattedDatesBetween(Date startDate, Date endDate) {
        StringBuilder formattedDates = new StringBuilder();
        java.util.Calendar calendar = java.util.Calendar.getInstance();
        calendar.setTime(startDate);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        while (!calendar.getTime().after(endDate)) {
            if (formattedDates.length() > 0) {
                formattedDates.append("|"); // 添加分隔符
            }
            formattedDates.append(dateFormat.format(calendar.getTime()));
            calendar.add(java.util.Calendar.DATE, 1);
        }
        return formattedDates.toString();
    }

    public String export(Long id) {
        Calendar calendarInfo = calendarMapper.selectCalendarById(id);
        if (calendarInfo == null) {
            throw new ServiceException("事历表不存在");
        }
        List<CalendarWeek> detail = detail(id);
        SXSSFWorkbook wb = new SXSSFWorkbook(500);
        SXSSFSheet sheet = wb.createSheet();
        wb.setSheetName(0, "Sheet1");
        // 标题
        CellStyle style = wb.createCellStyle();
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        style.setFillForegroundColor(IndexedColors.BLUE_GREY.getIndex());
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        Font titleFont = wb.createFont();
        titleFont.setFontName("Arial");
        titleFont.setFontHeightInPoints((short) 16);
        titleFont.setBold(true);
        style.setFont(titleFont);
        Row titleRow = sheet.createRow(0);
        titleRow.setHeightInPoints(30);
        Cell titleCell = titleRow.createCell(0);
        titleCell.setCellStyle(style);
        titleCell.setCellValue(calendarInfo.getCalendarName());
        sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(), titleRow.getRowNum(), titleRow.getRowNum(), detail.size()));

        SXSSFRow row1 = sheet.createRow(1);
        SXSSFCell cell1 = row1.createCell(0);
        cell1.setCellValue("周期\\周次");
        for (int i = 2; i < 9; i++) {
            SXSSFRow row = sheet.createRow(i);
            SXSSFCell cell = row.createCell(0);
            if (i == 8) {
                cell.setCellValue("日");
            } else {
                cell.setCellValue(ChineseNumToArabicNumUtil.arabicNumToChineseNum(i - 1));

            }
        }
        for (int i = 0; i < detail.size(); i++) {
            CalendarWeek calendarWeek = detail.get(i);
            if (StringUtils.isNotEmpty(calendarWeek.getWeekName())) {
                SXSSFCell row1Cell = row1.createCell(i + 1);
                row1Cell.setCellValue(calendarWeek.getWeekName());
            }
            for (int j = 0; j < calendarWeek.getDays().size(); j++) {
                CalendarDayVo day = calendarWeek.getDays().get(j);
                SXSSFRow row = sheet.getRow(day.getDayOfWeek() + 1);
                SXSSFCell cell = row.createCell(i + 1);
                Date date = day.getDay();
                java.util.Calendar calendar = java.util.Calendar.getInstance();
                calendar.setTime(date);
                int i1 = calendar.get(java.util.Calendar.DAY_OF_MONTH);
                String s;
                if (i1 == 1) {
                    s = day.getMonth();
                } else {
                    s = i1 + "";
                }
                if (StringUtils.isNotEmpty(day.getHolidayName())) {
                    s = s + "（" + day.getHolidayName() + ")";
                } else if (day.getHoliday()) {
                    s = s + "（假）";
                }
                cell.setCellValue(s);
            }
        }

        // 导出计划
        CalendarPlan planQuery = new CalendarPlan();
        planQuery.setCalendarId(id);
        planQuery.setDelStatus(BooleanEnum.TRUE.getCode());
        planQuery.setOrgCode(SecurityUtils.getAuthInfo().getOrgCode());
        List<CalendarPlan> plans = calendarPlanMapper.selectCalendarPlanList(planQuery);
        List<CalendarPlan> weekPlan = plans.stream().filter(e -> e.getPlanType().equals(1)).collect(Collectors.toList());
        List<CalendarPlan> monthPlan = plans.stream().filter(e -> e.getPlanType().equals(2)).collect(Collectors.toList());

        CellStyle styleL = wb.createCellStyle();
        styleL.setAlignment(HorizontalAlignment.LEFT);
        styleL.setWrapText(true);
        styleL.setVerticalAlignment(VerticalAlignment.TOP);

        Row monthPlanRow = sheet.createRow(9);
        monthPlanRow.setHeightInPoints(30);
        Cell monthPlantTitleCell = monthPlanRow.createCell(0);
        monthPlantTitleCell.setCellStyle(style);
        monthPlantTitleCell.setCellValue("教学月工作计划");
        sheet.addMergedRegion(new CellRangeAddress(monthPlanRow.getRowNum(), monthPlanRow.getRowNum(), 0, detail.size()));
        for (int i = 0; i < monthPlan.size(); i++) {
            CalendarPlan calendarPlan = monthPlan.get(i);
            SXSSFRow row = sheet.createRow(i + 10);
            SXSSFCell cell = row.createCell(0);
            cell.setCellValue(calendarPlan.getName());
            SXSSFCell cell2 = row.createCell(1);
            cell2.setCellStyle(styleL);
            cell2.setCellValue(calendarPlan.getPlanContent());
            row.setHeight((short) -1);
            sheet.addMergedRegion(new CellRangeAddress(row.getRowNum(), row.getRowNum(), 1, detail.size()));
        }

        Row weekPlanRow = sheet.createRow(10 + monthPlan.size());
        weekPlanRow.setHeightInPoints(30);
        Cell weekPlantTitleCell = weekPlanRow.createCell(0);
        weekPlantTitleCell.setCellStyle(style);
        weekPlantTitleCell.setCellValue("教学周工作计划");
        sheet.addMergedRegion(new CellRangeAddress(weekPlanRow.getRowNum(), weekPlanRow.getRowNum(), 0, detail.size()));
        for (int i = 0; i < weekPlan.size(); i++) {
            CalendarPlan calendarPlan = weekPlan.get(i);
            SXSSFRow row = sheet.createRow(i + 11 + monthPlan.size());
            SXSSFCell cell = row.createCell(0);
            cell.setCellValue(calendarPlan.getName());
            SXSSFCell cell2 = row.createCell(1);
            cell2.setCellStyle(styleL);
            cell2.setCellValue(calendarPlan.getPlanContent());
            row.setHeight((short) -1);
            sheet.addMergedRegion(new CellRangeAddress(row.getRowNum(), row.getRowNum(), 1, detail.size()));
        }


        UploadRet upload = uploadService.upload(wb, calendarInfo.getCalendarName() + ".xlsx");
        return upload.getUrl();
    }

    public List<CalendarWeek> detail(Long id) {
        Calendar calendar = calendarMapper.selectCalendarById(id);
        if (calendar == null) {
            throw new ServiceException("事历表不存在");
        }
        AuthInfo authInfo = SecurityUtils.getAuthInfo();
        List<GetYearListRet> yearList = xgkService.getYearList(authInfo.getOrgCode());
        CalendarDay queryDay = new CalendarDay();
        queryDay.setCalendarId(id);
        queryDay.setDelStatus(BooleanEnum.TRUE.getCode());
        queryDay.setOrgCode(authInfo.getOrgCode());
        List<CalendarDay> calendarDays = calendarDayMapper.selectCalendarDayList(queryDay);
        Map<Date, Integer> dayConfig = calendarDays.stream().collect(Collectors.toMap(CalendarDay::getDay, CalendarDay::getWorkFlg, (v1, v2) -> v2));
        // 自定义的假期
        CalendarHoliday queryHoliday = new CalendarHoliday();
        queryHoliday.setCalendarId(id);
        queryHoliday.setDelStatus(BooleanEnum.TRUE.getCode());
        queryHoliday.setOrgCode(authInfo.getOrgCode());
        List<CalendarHoliday> calendarHolidays = calendarHolidayMapper.selectCalendarHolidayList(queryHoliday);
        // 学期
        List<SemAddVacation> sem = yearList.stream().filter(e -> isX(DateUtils.parseDate(e.getBeginDay()), DateUtils.parseDate(e.getEndDay()), calendar.getCalendarBegin(), calendar.getCalendarEnd())).flatMap(e -> {
            return e.getSemAddVacation().stream().filter(j -> "1".equals(j.getType())).filter(j -> isX(DateUtils.parseDate(j.getBeginDay()), DateUtils.parseDate(j.getEndDay()), calendar.getCalendarBegin(), calendar.getCalendarEnd()));
        }).collect(Collectors.toList());
        // 所有教学周次
        List<SemWeek> teachWeeks = sem.stream().flatMap(e -> {
            return cookmenuWeekService.getWeekList(DateUtils.parseDate(e.getTeachWeekBeginDay()), DateUtils.parseDate(e.getEndDay())).stream();
        }).collect(Collectors.toList());
        // 寒暑假
        List<SemAddVacation> vacations = getVacations(yearList, calendar.getCalendarBegin(), calendar.getCalendarEnd());
        // 获取国家规定的放假和调休，并且自定义配置优先
        Map<Date, HolidayType> pubHolidayMap = holidayService.getHolidayDateMap(calendar.getCalendarBegin(), calendar.getCalendarEnd(), calendarHolidays);
        // 生成日历结构数据
        List<CalendarWeek> calendarWeeks = genCalendar(calendar.getCalendarBegin(), calendar.getCalendarEnd(), vacations, pubHolidayMap, teachWeeks);
        // 处理按天配置节假日
        filterConfig(calendarWeeks, dayConfig);
        List<CalendarHoliday> holidays = calendarHolidays.stream().filter(e -> {if (e.getHolidayName().equals("寒假") || e.getHolidayName().equals("暑假")){return true;}return false;}).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(holidays)){
            Map<Date,String > dateMap = holidays.stream().collect(Collectors.toMap(CalendarHoliday::getHolidayBegin, e -> e.getHolidayName(), (v1, v2) -> v2));
            for (CalendarWeek week : calendarWeeks){
                for (CalendarDayVo day : week.getDays()){
                    if (dateMap.containsKey(day.getDay())){
                        day.setHolidayName(dateMap.get(day.getDay()));
                    }
                }
            }
        }
        return calendarWeeks;
    }

    public List<CalendarMonth> getMonthCalendar(Long id) {
        Calendar calendar = calendarMapper.selectCalendarById(id);
        if (calendar == null) {
            throw new ServiceException("事历表不存在");
        }
//        AuthInfo authInfo = SecurityUtils.getAuthInfo();
        List<GetYearListRet> yearList = xgkService.getYearList(calendar.getOrgCode());
        CalendarDay queryDay = new CalendarDay();
        queryDay.setCalendarId(id);
        queryDay.setDelStatus(BooleanEnum.TRUE.getCode());
        queryDay.setOrgCode(calendar.getOrgCode());
        List<CalendarDay> calendarDays = calendarDayMapper.selectCalendarDayList(queryDay);
        Map<Date, Integer> dayConfig = calendarDays.stream().collect(Collectors.toMap(CalendarDay::getDay, CalendarDay::getWorkFlg, (v1, v2) -> v2));
        // 自定义的假期
        CalendarHoliday queryHoliday = new CalendarHoliday();
        queryHoliday.setCalendarId(id);
        queryHoliday.setDelStatus(BooleanEnum.TRUE.getCode());
        queryHoliday.setOrgCode(calendar.getOrgCode());
        List<CalendarHoliday> calendarHolidays = calendarHolidayMapper.selectCalendarHolidayList(queryHoliday);
        // 学期
        List<SemAddVacation> sem = yearList.stream().filter(e -> isX(DateUtils.parseDate(e.getBeginDay()), DateUtils.parseDate(e.getEndDay()), calendar.getCalendarBegin(), calendar.getCalendarEnd())).flatMap(e -> {
            return e.getSemAddVacation().stream().filter(j -> "1".equals(j.getType())).filter(j -> isX(DateUtils.parseDate(j.getBeginDay()), DateUtils.parseDate(j.getEndDay()), calendar.getCalendarBegin(), calendar.getCalendarEnd()));
        }).collect(Collectors.toList());
        // 所有教学周次
        List<SemWeek> teachWeeks = sem.stream().flatMap(e -> {
            return cookmenuWeekService.getWeekList(DateUtils.parseDate(e.getTeachWeekBeginDay()), DateUtils.parseDate(e.getEndDay())).stream();
        }).collect(Collectors.toList());
        // 寒暑假
        List<SemAddVacation> vacations = getVacations(yearList, calendar.getCalendarBegin(), calendar.getCalendarEnd());
        // 获取国家规定的放假和调休，并且自定义配置优先
        Map<Date, HolidayType> pubHolidayMap = holidayService.getHolidayDateMap(calendar.getCalendarBegin(), calendar.getCalendarEnd(), calendarHolidays);

        List<SemMonth> monthList = cookmenuWeekService.getMonthList(calendar.getCalendarBegin(), calendar.getCalendarEnd());
        List<CalendarMonth> calendarMonths = Lists.newArrayList();
        long l = System.currentTimeMillis();
        for (SemMonth month: monthList) {
            CalendarMonth calendarMonth = new CalendarMonth();
            calendarMonth.setMonthIndex(month.getMonthIndex());
            calendarMonth.setMonthName(ChineseNumToArabicNumUtil.arabicNumToChineseNum(month.getMonthIndex()) + "月");
            // 生成日历结构数据
            List<CalendarWeek> calendarWeeks = genCalendar(month.getBeginDay(), month.getEndDay(), vacations, pubHolidayMap, teachWeeks);
            // 处理按天配置节假日
            filterConfig(calendarWeeks, dayConfig);

            calendarMonth.setWeeks(calendarWeeks);
            if (month.getBeginDay().getTime() <= l && month.getEndDay().getTime() >= l) {
                calendarMonth.setCurFlg(true);
            }
            calendarMonths.add(calendarMonth);
        }

        List<CalendarHoliday> holidays = calendarHolidays.stream().filter(e -> {if (e.getHolidayName().equals("寒假") || e.getHolidayName().equals("暑假")){return true;}return false;}).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(holidays)){
            Map<Date,String > dateMap = holidays.stream().collect(Collectors.toMap(CalendarHoliday::getHolidayBegin, e -> e.getHolidayName(), (v1, v2) -> v2));
            for (CalendarMonth month : calendarMonths){
                for (CalendarWeek week : month.getWeeks()){
                    for (CalendarDayVo day : week.getDays()) {
                        if (dateMap.containsKey(day.getDay())) {
                            day.setHolidayName(dateMap.get(day.getDay()));
                        }
                    }
                }
            }
        }
        return calendarMonths;
    }

    public List<SemAddVacation> getVacations(List<GetYearListRet> yearList, Date begin, Date end) {
        List<SemAddVacation> vacations = yearList.stream().filter(e -> isX(DateUtils.parseDate(e.getBeginDay()), DateUtils.parseDate(e.getEndDay()), begin, end)).flatMap(e -> {
            return e.getSemAddVacation().stream().filter(j -> "2".equals(j.getType()));
        }).collect(Collectors.toList());

        return vacations;
    }

    public List<CalendarWeek> genCalendar(Date begin, Date end, List<SemAddVacation> vacations, Map<Date, HolidayType>  pubHolidayMap, List<SemWeek> teachWeeks) {
        // 寒暑假日期list
        List<Date> vacationDays = vacations.stream().flatMap(e -> {
            return getAllDay(DateUtils.parseDate(e.getBeginDay()), DateUtils.parseDate(e.getEndDay())).stream();
        }).collect(Collectors.toList());

        List<SemWeek> weekList = cookmenuWeekService.getWeekList(begin, end);
        List<CalendarWeek> calendarWeeks = Lists.newArrayList();
        Date now = DateUtils.getNowyyyyMMdd();
        for (int i  = 0; i < weekList.size(); i++) {
            SemWeek week = weekList.get(i);
            java.util.Calendar beginCalendar = java.util.Calendar.getInstance();
            beginCalendar.setTime(week.getBeginDay());
            java.util.Calendar endCalendar = java.util.Calendar.getInstance();
            endCalendar.setTime(week.getEndDay());
            List<CalendarDayVo> dayVos = Lists.newArrayList();
            while (!beginCalendar.after(endCalendar)) {
                CalendarDayVo day = new CalendarDayVo();
                day.setDay(beginCalendar.getTime());
                day.setMonth(ChineseNumToArabicNumUtil.arabicNumToChineseNum(beginCalendar.get(java.util.Calendar.MONTH) + 1) + "月");
                day.setDayOfMonth(ChineseNumToArabicNumUtil.arabicNumToChineseNum(beginCalendar.get(java.util.Calendar.DAY_OF_MONTH)) + "号");
//                String dayStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, beginCalendar.getTime());
                day.setHoliday(false);
                // 节假日/调休
                if (pubHolidayMap.containsKey(beginCalendar.getTime())) {
                    HolidayType holidayType = pubHolidayMap.get(beginCalendar.getTime());
                    boolean holiday = HolidayTypeEnum.HOLIDAY.getCode().equals(holidayType.getType()) || HolidayTypeEnum.CUR_HOLIDAY.getCode().equals(holidayType.getType());
                    day.setHoliday(holiday);
                    if (holiday && HolidayTypeEnum.CUR_HOLIDAY.getCode().equals(holidayType.getType())) {
                        day.setHolidayName(holidayType.getName());
                    }

                }
                // 寒暑假
                if (vacationDays.contains(beginCalendar.getTime())) {
                    day.setHoliday(true);
                }
                day.setDayOfWeek(DateUtils.getDayOfWeek(beginCalendar));
                if (day.getDay().compareTo(now) == 0) {
                    day.setCurFlg(true);
                }
                dayVos.add(day);
                beginCalendar.add(java.util.Calendar.DATE, 1);
            }
            SemWeek thisWeek = teachWeeks.stream().filter(e -> isX(e.getBeginDay(), e.getEndDay(), week.getBeginDay(), week.getEndDay())).findFirst().orElse(null);
            CalendarWeek calendarWeek = new CalendarWeek();
            calendarWeek.setSrotIndex(i + 1);
            if (thisWeek != null) {
                calendarWeek.setWeekIndex(thisWeek.getWeekIndex());
                calendarWeek.setWeekName("第" + ChineseNumToArabicNumUtil.arabicNumToChineseNum(thisWeek.getWeekIndex()) + "周");
            }
            calendarWeek.setDays(dayVos);
            if (week.getBeginDay().getTime() <= now.getTime() && week.getEndDay().getTime() >= now.getTime()) {
                calendarWeek.setCurFlg(true);
            }
            calendarWeeks.add(calendarWeek);
        }

        return calendarWeeks;
    }

    public void filterConfig(List<CalendarWeek> calendarWeeks, Map<Date, Integer> dayConfig) {
        calendarWeeks.stream().forEach(e -> {
            e.getDays().stream().forEach(j -> {
                if (dayConfig.containsKey(j.getDay())) {
                    j.setHoliday(BooleanEnum.TRUE.getCode().equals(dayConfig.get(j.getDay())) ? false : true);
                }
            });
        });
    }

    private boolean inDate(Date date, Date begin, Date end) {
        return date.getTime() >= begin.getTime() && date.getTime() <= end.getTime();
    }

    public boolean isX(Date begin1, Date end1, Date begin2, Date end2) {
        return inDate(begin1, begin2, end2) || inDate(end1, begin2, end2) || (begin1.getTime() < begin2.getTime() && end1.getTime() > end2.getTime());
    }

    public List<Date> getAllDay(Date begin, Date end) {
        java.util.Calendar beginCalendar = java.util.Calendar.getInstance();
        beginCalendar.setTime(begin);
        java.util.Calendar endCalendar = java.util.Calendar.getInstance();
        endCalendar.setTime(end);
        List<Date> dates = Lists.newArrayList();
        while (!beginCalendar.after(endCalendar)) {
            dates.add(beginCalendar.getTime());
            beginCalendar.add(java.util.Calendar.DATE, 1);
        }
        return dates;
    }
}
